package com.ts.code.creator;

import com.ts.code.creator.creator.CompositeCodeCreator;
import com.ts.code.creator.enums.CreateFileEnum;
import com.ts.code.creator.enums.ParamTypeEnum;
import com.ts.code.creator.enums.RetTypeEnum;
import com.ts.code.creator.creator.ClassFileSearch;
import com.ts.code.creator.util.CodeProperties;
import com.ts.code.creator.util.CodePropertiesUtil;
import com.ts.code.creator.util.CreateCodeContext;
import com.ts.code.creator.util.FileUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.ts.code.creator.util.StringUtil;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

public class CreateCodeGui extends DialogWrapper {
    private JPanel contentPanel;
    private JTextField methodName;
    private JTextField remark;
    private JComboBox paramType;
    private JComboBox retType;
    private JComboBox serviceList;
    private JTextField serviceAlias;
    private JTextField author;
    private JTextField entityName;
    private JTextField entityAlias;
    private JCheckBox adminControllerChecked;
    private JTextField adminControllerPath;
    private JCheckBox adminServiceChecked;
    private JCheckBox adminServiceImplChecked;
    private JTextField adminServicePath;
    private JTextField adminServiceImplPath;
    private JTextField providerInterfacePath;
    private JTextField serviceControllerPath;
    private JTextField serviceServicePath;
    private JTextField serviceServiceImplPath;
    private JButton buildBtn;
    private JCheckBox adminParamChecked;
    private JTextField adminParamPath;
    private JCheckBox adminVOChecked;
    private JTextField adminVOPath;
    private JCheckBox providerInterfaceChecked;
    private JCheckBox providerReqDTOchecked;
    private JTextField providerReqDTOPath;
    private JCheckBox providerRespDTOChecked;
    private JTextField providerRespDTOPath;
    private JCheckBox serviceControllerChecked;
    private JCheckBox serviceServiceChecked;
    private JCheckBox serviceServiceImplChecked;
    private CreateCodeContext context;
    private ClassFileSearch classFileSearch;

    protected CreateCodeGui(@Nullable Project project, boolean canBeParent, CreateCodeContext context) {
        super(project, canBeParent);
        this.context = context;
        this.classFileSearch = new ClassFileSearch(context);

        CodeProperties properties = CodePropertiesUtil.get();

        setTitle("创建方法");
        // 服务列表
        List<String> services = FileUtil.listServices(project.getBasePath());
        services.forEach(t -> serviceList.addItem(t));

        // 参数类型
        for (ParamTypeEnum value : ParamTypeEnum.values()) {
            paramType.addItem(value.getName());
        }
        // 返回类型
        for (RetTypeEnum value : RetTypeEnum.values()) {
            retType.addItem(value.getName());
        }

        String controllerName = context.getAdminControllerPackageName() + "." + context.getAdminControllerClassName();
        CodeProperties.EntityAlias ea = properties.getEntityAlias(controllerName);
        if (ea != null) {
            entityName.setText(ea.getEntityName());
            entityAlias.setText(ea.getEntityAlias());
        } else {
            entityName.setText(context.getEntityName());
            entityAlias.setText(context.getEntityName());
        }

        // 设置初始值
        if (StringUtil.isNotBlank(properties.getAuthor())) {
            author.setText(properties.getAuthor());
        }
        if (StringUtil.isNotBlank(properties.getService())) {
            serviceList.setSelectedItem(properties.getService());
            // 服务别名
            if (StringUtil.isNotBlank(properties.getServiceAlias())) {
                serviceAlias.setText(properties.getServiceAlias());
            } else {
                String alias = properties.getService().substring(properties.getService().lastIndexOf("-") + 1);
                serviceAlias.setText(alias);
            }
        }
        if (StringUtil.isNotBlank(properties.getParamType())) {
            paramType.setSelectedItem(properties.getParamType());
        }
        if (StringUtil.isNotBlank(properties.getRetType())) {
            retType.setSelectedItem(properties.getRetType());
        }

        serviceList.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String serviceName = serviceList.getSelectedItem().toString();
                String serviceAlias = serviceName.substring(serviceName.lastIndexOf("-") + 1);
                CreateCodeGui.this.serviceAlias.setText(serviceAlias);
            }
        });

        //
        buildBtn.addActionListener(e -> resetFilePath());

        init();
    }

    @Override
    protected @Nullable JComponent createCenterPanel() {
        return contentPanel;
    }

    private void resetFilePath() {
        String methodName = this.methodName.getText();
        if (StringUtil.isBlank(methodName)) {
            return;
        }

        context.setAuthor(author.getText());
        context.setMethodName(methodName);
        context.setRemark(remark.getText());
        context.setService(serviceList.getSelectedItem().toString());
        context.setServiceAlias(serviceAlias.getText());
        context.setRetTypeEnum(RetTypeEnum.getByName(retType.getSelectedItem().toString()));
        context.setParamTypeEnum(ParamTypeEnum.getByName(paramType.getSelectedItem().toString()));
        context.setEntityName(entityName.getText());
        context.setEntityAlias(entityAlias.getText());

        // 修改方法的
        setJavaFilePath(adminControllerPath, classFileSearch.adminController());
        setJavaFilePath(adminServicePath, classFileSearch.adminService());
        setJavaFilePath(adminServiceImplPath, classFileSearch.adminServiceImpl());
        setJavaFilePath(providerInterfacePath, classFileSearch.providerInterface());
        setJavaFilePath(serviceControllerPath, classFileSearch.serviceController());
        setJavaFilePath(serviceServicePath, classFileSearch.serviceService());
        setJavaFilePath(serviceServiceImplPath, classFileSearch.serviceServiceImpl());

        RetTypeEnum retTypeEnum = RetTypeEnum.getByName(retType.getSelectedItem().toString());
        ParamTypeEnum paramTypeEnum = ParamTypeEnum.getByName(paramType.getSelectedItem().toString());

        // 新建文件
        setCreateJavaFilePath(adminVOPath, classFileSearch.adminVO(), RetTypeEnum.isCreateRetClass(retTypeEnum));
        setCreateJavaFilePath(providerRespDTOPath, classFileSearch.providerRespDTO(), RetTypeEnum.isCreateRetClass(retTypeEnum));
        setCreateJavaFilePath(adminParamPath, classFileSearch.adminParam(), ParamTypeEnum.isCreateParamClass(paramTypeEnum));
        setCreateJavaFilePath(providerReqDTOPath, classFileSearch.providerReqDTO(), ParamTypeEnum.isCreateParamClass(paramTypeEnum));
    }

    private void setJavaFilePath(JTextField textField, String path) {
        if (FileUtil.exist(path)) {
            textField.setText(path);
        } else {
            textField.setText("没找到文件，请检查实体别名是否正确、服务包名是否正确");
        }
    }

    private void setCreateJavaFilePath(JTextField textField, String path, boolean isCreate) {
        if (isCreate) {
            String dirPath = path.substring(0, path.lastIndexOf("/"));
            if (FileUtil.exist(dirPath)) {
                textField.setText(path);
            } else {
                textField.setText("没找到文件夹，请检查实体别名是否正确、服务包名是否正确");
            }
        } else {
            textField.setText("无需创建");
        }
    }

    @Override
    protected void doOKAction() {
        // 参数
        context.setAuthor(author.getText());
        context.setMethodName(methodName.getText());
        context.setRemark(remark.getText());
        context.setService(serviceList.getSelectedItem().toString());
        context.setServiceAlias(serviceAlias.getText());
        context.setRetTypeEnum(RetTypeEnum.getByName(retType.getSelectedItem().toString()));
        context.setParamTypeEnum(ParamTypeEnum.getByName(paramType.getSelectedItem().toString()));
        context.setEntityName(entityName.getText());
        context.setEntityAlias(entityAlias.getText());
        // 选中要生成的文件
        if (adminControllerChecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.ADMIN_CONTROLLER);
        }
        if (adminServiceChecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.ADMIN_SERVICE);
        }
        if (adminServiceImplChecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.ADMIN_SERVICE_IMPL);
        }
        if (adminParamChecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.ADMIN_PARAM);
        }
        if (adminVOChecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.ADMIN_VO);
        }
        if (providerInterfaceChecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.PROVIDER_INTERFACE);
        }
        if (providerReqDTOchecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.PROVIDER_REQDTO);
        }
        if (providerRespDTOChecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.PROVIDER_RESPDTO);
        }
        if (serviceControllerChecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.SERVICE_CONTROLLER);
        }
        if (serviceServiceChecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.SERVICE_SERVICE);
        }
        if (serviceServiceImplChecked.isSelected()) {
            context.getCreateFileTypes().add(CreateFileEnum.SERVICE_SERVICE_IMPL);
        }

        CompositeCodeCreator creator = new CompositeCodeCreator(context);
        creator.create();

        String controllerName = context.getAdminControllerPackageName() + "." + context.getAdminControllerClassName();

        // 保存参数
        CodeProperties properties = new CodeProperties();
        properties.setAuthor(author.getText());
        properties.setService(serviceList.getSelectedItem().toString());
        properties.setServiceAlias(serviceAlias.getText());
        properties.setRetType(retType.getSelectedItem().toString());
        properties.setParamType(paramType.getSelectedItem().toString());
        properties.add(controllerName, entityName.getText(), entityAlias.getText());
        CodePropertiesUtil.save(properties);
        super.doOKAction();
    }

}
